home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / sprite.X11R3 / RCS / spriteCursor.c,v < prev    next >
Encoding:
Text File  |  1989-11-19  |  46.3 KB  |  1,860 lines

  1. head     1.12;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.12
  10. date     89.11.18.20.57.19;  author tve;  state Exp;
  11. branches ;
  12. next     1.11;
  13.  
  14. 1.11
  15. date     88.03.27.21.17.46;  author deboor;  state Exp;
  16. branches ;
  17. next     1.10;
  18.  
  19. 1.10
  20. date     88.02.19.17.36.58;  author deboor;  state Exp;
  21. branches ;
  22. next     1.9;
  23.  
  24. 1.9
  25. date     87.08.21.20.36.26;  author deboor;  state Exp;
  26. branches ;
  27. next     1.8;
  28.  
  29. 1.8
  30. date     87.07.07.17.59.31;  author deboor;  state Exp;
  31. branches ;
  32. next     1.7;
  33.  
  34. 1.7
  35. date     87.06.30.19.11.02;  author deboor;  state Exp;
  36. branches ;
  37. next     1.5;
  38.  
  39. 1.5
  40. date     87.06.21.17.27.25;  author deboor;  state Exp;
  41. branches ;
  42. next     1.4;
  43.  
  44. 1.4
  45. date     87.06.20.19.56.38;  author deboor;  state Exp;
  46. branches ;
  47. next     1.3;
  48.  
  49. 1.3
  50. date     87.06.20.14.58.26;  author deboor;  state Exp;
  51. branches ;
  52. next     1.2;
  53.  
  54. 1.2
  55. date     87.06.20.14.57.33;  author deboor;  state Exp;
  56. branches ;
  57. next     1.1;
  58.  
  59. 1.1
  60. date     87.06.20.14.56.02;  author deboor;  state Exp;
  61. branches ;
  62. next     ;
  63.  
  64.  
  65. desc
  66. @Functions for doing a software cursor
  67. @
  68.  
  69.  
  70. 1.12
  71. log
  72. @first working version with CG4 and CG6 for SPARC. CG4 for sun3 not yet ok.
  73. @
  74. text
  75. @/*-
  76.  * spriteCursor.c --
  77.  *    Functions for maintaining the Sun software cursor...
  78.  *
  79.  * Copyright (c) 1987 by the Regents of the University of California
  80.  *
  81.  * Permission to use, copy, modify, and distribute this
  82.  * software and its documentation for any purpose and without
  83.  * fee is hereby granted, provided that the above copyright
  84.  * notice appear in all copies.  The University of California
  85.  * makes no representations about the suitability of this
  86.  * software for any purpose.  It is provided "as is" without
  87.  * express or implied warranty.
  88.  */
  89.  
  90. #ifndef lint
  91. static char rcsid[] =
  92. "$Header: /mic/X11R3/src/cmds/Xsp/ddx/sprite/RCS/spriteCursor.c,v 1.12 89/10/23 19:43:09 tve Exp $ SPRITE (Berkeley)";
  93. #endif lint
  94. /*
  95.  * A cursor can be in one of 3 states:
  96.  *    IN        It is actually in the frame buffer.
  97.  *    OUT       It is not in the frame buffer and the screen should be
  98.  *              consulted for new screenBits before it is replaced.
  99.  *    XING      It is changing state. Used when calling mfb functions to
  100.  *              play with the cursor. Avoids infinite recursion, you know.
  101.  *    
  102.  * Two references for cursor coordinates are being used in this code. 
  103.  * The outside world (dix code) and most of spriteCursors use the cursor 
  104.  * hot-spot as a reference for the cursor's location. spriteCursor internal 
  105.  * code uses the top-left corner of the cursor glyph as a reference 
  106.  * for painting operations. 
  107.  * 
  108.  */
  109.  
  110. #define NEED_EVENTS            /* For SetCursorPosition */
  111. #include    "spriteddx.h"
  112. #include    <windowstr.h>
  113. #include    <regionstr.h>
  114. #include    <dix.h>
  115. #include    <dixstruct.h>
  116. #include    <opaque.h>
  117. #include    <servermd.h>
  118.  
  119. static CursorPtr  currentCursor = NullCursor;    /* Cursor being displayed */
  120. static BoxRec        currentLimits;        /* Box w/in which the hot spot
  121.                          * must stay. */
  122. /*
  123.  * There are four window functions which bypass the usual GC validation
  124.  * path (PaintWindow{Background,Border}, CopyWindow & ClearToBackground)
  125.  * so we must go out of
  126.  * our way to protect the cursor from them. This is accomplished by
  127.  * intercepting the two screen calls which change the window vectors so
  128.  * we can note when they do and substitute our own function which figures
  129.  * out what's going to be nuked and makes sure the cursor isn't there.
  130.  * The structure for the window is tracked in a somewhat sneaky way:
  131.  * we create a new resource class (not type) and use that to associate
  132.  * the WinPrivRec with the window (using the window's id) in the resource
  133.  * table. This makes it easy to find and has the added benefit of freeing
  134.  * the private data when the window is destroyed.
  135.  */
  136. typedef struct {
  137.     void    (*PaintWindowBackground)();
  138.     void    (*PaintWindowBorder)();
  139.     void    (*CopyWindow)();
  140.     void        (*SaveAreas)();
  141.     RegionPtr   (*RestoreAreas)();
  142. } WinPrivRec, *WinPrivPtr;
  143.  
  144. static int    wPrivClass;        /* Resource class for icky private
  145.                      * window structure (WinPrivRec)
  146.                      * needed to protect the cursor
  147.                      * from background/border paintings */
  148.  
  149. /*-
  150.  *-----------------------------------------------------------------------
  151.  * spriteInitCursor --
  152.  *    Initialize the cursor module...
  153.  *
  154.  * Results:
  155.  *    None.
  156.  *
  157.  * Side Effects:
  158.  *    currentCursor is set to NullCursor.
  159.  *
  160.  *-----------------------------------------------------------------------
  161.  */
  162. void
  163. spriteInitCursor ()
  164. {
  165.     currentCursor = NullCursor;
  166.     wPrivClass = CreateNewResourceClass();
  167. }
  168.  
  169. /*-
  170.  *-----------------------------------------------------------------------
  171.  * spriteStencil --
  172.  *    Return the data for a bitmap made by squishing the source bitmap
  173.  *    data through the mask bitmap data. If invert is TRUE, the source
  174.  *    data are inverted before being squished through.
  175.  *
  176.  * Results:
  177.  *    An array of data suitable for passing to PutImage
  178.  *
  179.  * Side Effects:
  180.  *    None.
  181.  *
  182.  *-----------------------------------------------------------------------
  183.  */
  184. static unsigned char *
  185. spriteStencil (source, mask, w, h, invert)
  186.     register unsigned char *source;      /* Source data */
  187.     register unsigned char *mask;        /* Mask data */
  188.     int              w;            /* Width of both */
  189.     int              h;            /* Height of both */
  190.     Bool          invert;       /* Invert source before squishing */
  191. {
  192.     unsigned char          *result;
  193.     register unsigned char *r;
  194.     register int  nbytes;
  195.  
  196.     nbytes = h * PixmapBytePad (w, 1);
  197.     result = (unsigned char *)Xalloc(nbytes);
  198.  
  199.     for (r = result; nbytes--; source++, r++) {
  200.     *r = (invert ? ~ *source : *source) & (mask ? *mask++ : ~0);
  201.     }
  202.  
  203.     return (result);
  204. }
  205.  
  206. /*-
  207.  *-----------------------------------------------------------------------
  208.  * spriteGetPixel --
  209.  *    Given an rgb value, find an equivalent pixel value for it.
  210.  *
  211.  * Results:
  212.  *    The pixel value.
  213.  *
  214.  * Side Effects:
  215.  *    A colormap entry might be allocated...
  216.  *
  217.  *-----------------------------------------------------------------------
  218.  */
  219. static Pixel
  220. spriteGetPixel (pScreen, r, g, b)
  221.     ScreenPtr      pScreen;  /* Screen to allocate from */
  222.     unsigned short r;        /* Red value to use */
  223.     unsigned short g;        /* Green value to use */
  224.     unsigned short b;        /* Blue value to use */
  225. {
  226.     ColormapPtr cmap;
  227.     Pixel       pix;
  228.  
  229.     cmap = (ColormapPtr) LookupID(pScreen->defColormap, RT_COLORMAP, RC_CORE);
  230.     if (!cmap) {
  231.     FatalError("Can't find default colormap in spriteGetPixel\n");
  232.     }
  233.     if (AllocColor(cmap, &r, &g, &b, &pix, 0)) {
  234.     FatalError("Can't alloc pixel (%d,%d,%d) in spriteGetPixel\n",
  235.            r, g, b);
  236.     }
  237.     return (pix);
  238. }
  239. /*-
  240.  *-----------------------------------------------------------------------
  241.  * spriteRealizeCursor --
  242.  *    Realize a cursor for a specific screen. Eventually it will have
  243.  *    to deal with the allocation of a special pixel from the system
  244.  *    colormap, but for now it's fairly simple. Just have to create
  245.  *    pixmaps.
  246.  *
  247.  * Results:
  248.  *
  249.  * Side Effects:
  250.  *    A CrPrivRec is allocated and filled and stuffed into the Cursor
  251.  *    structure given us.
  252.  *
  253.  *-----------------------------------------------------------------------
  254.  */
  255. Bool
  256. spriteRealizeCursor (pScreen, pCursor)
  257.     ScreenPtr      pScreen;      /* Screen for which the cursor should be */
  258.                 /* realized */
  259.     CursorPtr      pCursor;      /* Cursor to realize */
  260. {
  261.     register CrPrivPtr pPriv;
  262.     int         bufWidth;
  263.     GC         *pGC;        /* GC for initializing the source and
  264.                  * invSource pixmaps... */
  265.     unsigned char *stencil;
  266.     BITS32      status;
  267.  
  268.  
  269.     pGC = GetScratchGC (1, pScreen);
  270.  
  271.     pPriv = (CrPrivPtr) Xalloc(sizeof(CrPrivRec));
  272.     pPriv->state = CR_OUT;
  273.     pCursor->devPriv[pScreen->myNum] = (pointer) pPriv;
  274.  
  275.     bufWidth = 2 * pCursor->width;
  276.  
  277.     pPriv->fg = spriteGetPixel(pScreen, pCursor->foreRed,
  278.                 pCursor->foreGreen,
  279.                 pCursor->foreBlue);
  280.     pPriv->bg = spriteGetPixel(pScreen, pCursor->backRed,
  281.                 pCursor->backGreen,
  282.                 pCursor->backBlue);
  283.  
  284.     /*
  285.      * Create the two pixmaps for the off-screen manipulation of the
  286.      * cursor image. The screenBits pixmap is used to hold the contents of
  287.      * the screen before the cursor is put down and the temp pixmap exists
  288.      * to avoid having to create a pixmap each time the cursor is rop'ed
  289.      * in. Both are made the same depth as the screen, for obvious
  290.      * reasons. 
  291.      */
  292.     pPriv->screenBits =
  293.     (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, bufWidth,
  294.                           2 * pCursor->height,
  295.                           pScreen->rootDepth,
  296.                           ZPixmap);
  297.     pPriv->temp =
  298.     (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, bufWidth,
  299.                           2 * pCursor->height,
  300.                           pScreen->rootDepth,
  301.                           ZPixmap);
  302.  
  303.     /*
  304.      * The source and invSource bitmaps are a bit trickier. The idea is to
  305.      * use the source in a PushPixels operation on the foreground pixel of
  306.      * the cursor and the invSource in a PushPixels on the background
  307.      * pixel of the cursor. The tricky thing is both bitmaps must be
  308.      * created from the source bits after being masked by the mask bits.
  309.      * This must, sadly, be done by hand b/c the ddx interface isn't quite
  310.      * rich enough to push a tile through a bitmap. 
  311.      */
  312.     pPriv->source =
  313.     (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, pCursor->width,
  314.                           pCursor->height, 1,
  315.                           XYBitmap);
  316.     ValidateGC(pPriv->source, pGC);
  317.     stencil = spriteStencil(pCursor->source, pCursor->mask,
  318.              pCursor->width, pCursor->height,
  319.              FALSE);
  320.     (*pGC->PutImage) (pPriv->source, pGC, 1,
  321.               0, 0,
  322.               pCursor->width, pCursor->height,
  323.               0,
  324.               XYPixmap,
  325.               stencil);
  326.     Xfree(stencil);
  327.  
  328.     pPriv->srcGC = spriteCreatePrivGC((DrawablePtr)pScreen->devPrivate,
  329.                       GCForeground, &pPriv->fg, &status);
  330.     ValidateGC((DrawablePtr) pScreen->devPrivate, pPriv->srcGC);
  331.  
  332.     pPriv->invSource =
  333.     (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, pCursor->width,
  334.                           pCursor->height, 1,
  335.                           XYBitmap);
  336.     ValidateGC(pPriv->invSource, pGC);
  337.     stencil = spriteStencil(pCursor->source, pCursor->mask,
  338.              pCursor->width, pCursor->height,
  339.              TRUE);
  340.     (*pGC->PutImage) (pPriv->invSource, pGC, 1,
  341.               0, 0,
  342.               pCursor->width, pCursor->height,
  343.               0,
  344.               XYPixmap,
  345.               stencil);
  346.     Xfree(stencil);
  347.  
  348.     pPriv->invSrcGC = spriteCreatePrivGC((DrawablePtr)pScreen->devPrivate,
  349.                     GCForeground, &pPriv->bg, &status);
  350.     ValidateGC((DrawablePtr) pScreen->devPrivate, pPriv->invSrcGC);
  351.  
  352.     FreeScratchGC (pGC);
  353. }
  354.  
  355. /*-
  356.  *-----------------------------------------------------------------------
  357.  * spriteUnrealizeCursor --
  358.  *    Free up the extra state created by spriteRealizeCursor.
  359.  *
  360.  * Results:
  361.  *    TRUE.
  362.  *
  363.  * Side Effects:
  364.  *    All the pixmaps etc. created by spriteRealizeCursor are destroyed
  365.  *    and the private structure is freed.
  366.  *
  367.  *-----------------------------------------------------------------------
  368.  */
  369. Bool
  370. spriteUnrealizeCursor (pScreen, pCursor)
  371.     ScreenPtr      pScreen;      /* Screen for which to unrealize the cursor */
  372.     CursorPtr      pCursor;      /* Cursor to unrealize */
  373. {
  374.     CrPrivPtr   pPriv;
  375.  
  376.     if (currentCursor == pCursor) {
  377.     spriteRemoveCursor();
  378.     currentCursor = NullCursor;
  379.     }
  380.     pPriv = (CrPrivPtr) pCursor->devPriv[pScreen->myNum];
  381.  
  382.     (*pScreen->DestroyPixmap) (pPriv->source);
  383.     (*pScreen->DestroyPixmap) (pPriv->invSource);
  384.     (*pScreen->DestroyPixmap) (pPriv->screenBits);
  385.     (*pScreen->DestroyPixmap) (pPriv->temp);
  386.     /*
  387.      * XXX: Deallocate pixels 
  388.      */
  389.     FreeScratchGC(pPriv->srcGC);
  390.     FreeScratchGC(pPriv->invSrcGC);
  391.  
  392.     Xfree(pPriv);
  393.  
  394.     return TRUE;
  395. }
  396.  
  397. /*-
  398.  *-----------------------------------------------------------------------
  399.  * spriteSetCursorPosition --
  400.  *    Alter the position of the current cursor. The x and y coordinates
  401.  *    are assumed to be legal for the given screen.
  402.  *
  403.  * Results:
  404.  *    TRUE.
  405.  *
  406.  * Side Effects:
  407.  *    The pScreen, x, and y fields of the current pointer's private data
  408.  *    are altered to reflect the new values. I.e. moving the cursor to
  409.  *    a different screen moves the pointer there as well. Helpful...
  410.  *
  411.  *-----------------------------------------------------------------------
  412.  */
  413. Bool
  414. spriteSetCursorPosition (pScreen, hotX, hotY, genEvent)
  415.     ScreenPtr      pScreen;      /* New screen for the cursor */
  416.     unsigned int  hotX;            /* New absolute X coordinate for the cursor */
  417.     unsigned int  hotY;            /* New absolute Y coordinate for the cursor */
  418.     Bool          genEvent;     /* Generate a motion event */
  419. {
  420.     DevicePtr      pDev;
  421.     PtrPrivPtr      pptrPriv;
  422.  
  423.     if (currentCursor == NullCursor) {
  424.     return FALSE;
  425.     } else {
  426.     pDev = LookupPointerDevice();
  427.     
  428.     pptrPriv = (PtrPrivPtr) pDev->devicePrivate;
  429.  
  430.     if (genEvent) {
  431.         /*
  432.          * If we have to generate a motion event here, we need to
  433.          * flush any current motion events to move the cursor to the
  434.          * right place, etc.
  435.          */
  436.         ProcessInputEvents();
  437.     }
  438.     
  439.     if (pScreen == pptrPriv->pScreen) {
  440.         /*
  441.          * Cursor staying on the same screen, let spriteMoveCursor
  442.          * worry about positioning the beastie
  443.          */
  444.         spriteMoveCursor (pScreen, hotX, hotY);
  445.     } else {
  446.         /*
  447.          * Now nuke the cursor and switch its position to the other
  448.          * screen.
  449.          */
  450.         spriteRemoveCursor();
  451.         pptrPriv->pScreen = pScreen;
  452.     }
  453.     pptrPriv->x = hotX;
  454.     pptrPriv->y = hotY;
  455.  
  456.     if (genEvent) {
  457.         /*
  458.          * Have to generate a motion event for DIX. We use the time of
  459.          * the last event plus 1 millisecond since we can't do anything
  460.          * else useful and I assume there will be more than 1 ms between
  461.          * events...maybe.
  462.          */
  463.         xEvent    motion;
  464.         
  465.         motion.u.keyButtonPointer.rootX = hotX;
  466.         motion.u.keyButtonPointer.rootY = hotY;
  467.         lastEventTimeMS += 1;
  468.         motion.u.keyButtonPointer.time = lastEventTimeMS;
  469.         motion.u.u.type = MotionNotify;
  470.         (* pDev->processInputProc) (&motion, pDev);
  471.     }
  472.     return TRUE;
  473.     }
  474. }
  475.  
  476. /*-
  477.  *-----------------------------------------------------------------------
  478.  * spriteCursorLimits --
  479.  *    Return a box within which the given cursor may move on the given
  480.  *    screen. We assume that the HotBox is actually on the given screen,
  481.  *    since dix knows that size.
  482.  *
  483.  * Results:
  484.  *    A box for the hot spot corner of the cursor.
  485.  *
  486.  * Side Effects:
  487.  *    None.
  488.  *
  489.  *-----------------------------------------------------------------------
  490.  */
  491. void
  492. spriteCursorLimits (pScreen, pCursor, pHotBox, pResultBox)
  493.     ScreenPtr      pScreen;      /* Screen on which limits are desired */
  494.     CursorPtr      pCursor;      /* Cursor whose limits are desired */
  495.     BoxPtr        pHotBox;      /* Limits for pCursor's hot point */
  496.     BoxPtr        pResultBox;    /* RETURN: limits for hot spot */
  497. {
  498.     *pResultBox = *pHotBox;
  499. }
  500.  
  501. /*-
  502.  *-----------------------------------------------------------------------
  503.  * spriteDisplayCursor --
  504.  *    Set the current cursor.
  505.  *
  506.  * Results:
  507.  *    TRUE.
  508.  *
  509.  * Side Effects:
  510.  *    The value of currentCursor is altered. Note that the cursor is
  511.  *    *not* placed in the frame buffer until RestoreCursor is called.
  512.  *    Instead, the cursor is marked as out, which will cause it to
  513.  *    be replaced.
  514.  *
  515.  *-----------------------------------------------------------------------
  516.  */
  517. Bool
  518. spriteDisplayCursor (pScreen, pCursor)
  519.     ScreenPtr      pScreen;      /* Screen on which to display cursor */
  520.     CursorPtr      pCursor;      /* Cursor to display */
  521. {
  522.     if (currentCursor) {
  523.     spriteRemoveCursor();
  524.     }
  525.  
  526.     currentCursor = pCursor;
  527.  
  528.     ((CrPrivPtr)pCursor->devPriv[pScreen->myNum])->state = CR_OUT;
  529.     spriteCursorGone();
  530.  
  531.     return TRUE;
  532. }
  533.  
  534. /*-
  535.  *-----------------------------------------------------------------------
  536.  * spriteRecolorCursor --
  537.  *    Change the color of a cursor.
  538.  *
  539.  * Results:
  540.  *    None.
  541.  *
  542.  * Side Effects:
  543.  *    If the screen is a color one
  544.  *
  545.  *-----------------------------------------------------------------------
  546.  */
  547. void
  548. spriteRecolorCursor (pScreen, pCursor, displayed)
  549.     ScreenPtr      pScreen;      /* Screen for which the cursor is to be */
  550.                 /* recolored */
  551.     CursorPtr      pCursor;      /* Cursor to recolor */
  552.     Bool          displayed;    /* True if pCursor being displayed now */
  553. {
  554.     CrPrivPtr      pPriv;
  555.     /*
  556.      * XXX: will have to alter the colormap entries of the foreground and
  557.      * background pixels. For now, just change the pixels...
  558.      */
  559.  
  560.     if (displayed) {
  561.     spriteRemoveCursor();
  562.     }
  563.  
  564.     pPriv = (CrPrivPtr)pCursor->devPriv[pScreen->myNum];
  565.     pPriv->fg = spriteGetPixel(pScreen,
  566.                 pCursor->foreRed,
  567.                 pCursor->foreGreen,
  568.                 pCursor->foreBlue);
  569.     ChangeGC (pPriv->srcGC, GCForeground, &pPriv->fg);
  570.     ValidateGC (pScreen->devPrivate, pPriv->srcGC);
  571.     
  572.     pPriv->bg = spriteGetPixel (pScreen,
  573.                  pCursor->backRed,
  574.                  pCursor->backGreen,
  575.                  pCursor->backBlue);
  576.     ChangeGC (pPriv->invSrcGC, GCForeground, &pPriv->bg);
  577.     ValidateGC (pScreen->devPrivate, pPriv->invSrcGC);
  578. }
  579.  
  580. /*-
  581.  *-----------------------------------------------------------------------
  582.  * spritePointerNonInterestBox --
  583.  *    Set up things to ignore uninteresting mouse events. Sorry.
  584.  *
  585.  * Results:
  586.  *
  587.  * Side Effects:
  588.  *
  589.  *-----------------------------------------------------------------------
  590.  */
  591. /*ARGSUSED*/
  592. void
  593. spritePointerNonInterestBox (pScreen, pBox)
  594.     ScreenPtr      pScreen;  /* Screen for cursor */
  595.     BoxPtr        pBox;        /* Box inside of which motions are boring */
  596. {
  597. }
  598.  
  599. /*-
  600.  *-----------------------------------------------------------------------
  601.  * spriteConstrainCursor --
  602.  *    Make it so the current pointer doesn't let the cursor's
  603.  *      hot-spot wander out of the specified box.
  604.  *    
  605.  * Results:
  606.  *    None.
  607.  *
  608.  * Side Effects:
  609.  *    currentLimits is overwritten.
  610.  *
  611.  *-----------------------------------------------------------------------
  612.  */
  613. /*ARGSUSED*/
  614. void
  615. spriteConstrainCursor (pScreen, pBox)
  616.     ScreenPtr      pScreen;      /* Screen to which it should be constrained */
  617.     BoxPtr        pBox;            /* Box in which... */
  618. {
  619.     currentLimits = *pBox;
  620. }
  621.  
  622. /*-
  623.  *-----------------------------------------------------------------------
  624.  * spriteRemoveCursor --
  625.  *    Remove the current cursor from the screen, if it hasn't been removed
  626.  *    already.
  627.  *
  628.  * Results:
  629.  *    None.
  630.  *
  631.  * Side Effects:
  632.  *    If the cursor is removed, the state field of the cursor-private
  633.  *    structure is set to CR_OUT. In addition, spriteCursorGone is called.
  634.  *
  635.  *-----------------------------------------------------------------------
  636.  */
  637. void
  638. spriteRemoveCursor ()
  639. {
  640.     CrPrivPtr      pPriv;        /* Private data for this cursor */
  641.     ScreenPtr      pScreen;      /* Screen on which the cursor is */
  642.     PtrPrivPtr      pPtrPriv;    /* XXX: Pointer private data */
  643.     DevicePtr      pDev;
  644.     GC              *pGC;
  645.  
  646.     if (currentCursor == NullCursor) {
  647.     return;
  648.     }
  649.  
  650.     pDev = LookupPointerDevice();
  651.  
  652.     pPtrPriv = (PtrPrivPtr) pDev->devicePrivate;
  653.     pScreen = pPtrPriv->pScreen;
  654.     
  655.     pPriv = (CrPrivPtr)currentCursor->devPriv[pScreen->myNum];
  656.  
  657.     if (pPriv->state == CR_IN) {
  658.     /*
  659.      * XXX: Makes use of the devPrivate field of the screen. This *must*
  660.      * be a pixmap representing the entire screen. How else can I get a
  661.      * pixmap to draw to?
  662.      */
  663.  
  664.     pGC = spriteFbs[pScreen->myNum].pGC;
  665.  
  666.     pPriv->state = CR_XING;
  667.     pGC->stateChanges |= (GCForeground|GCBackground);    
  668.         /* Need to set some bits */
  669.     ValidateGC((DrawablePtr)pScreen->devPrivate, pGC);
  670.     (* pGC->CopyArea) (pPriv->screenBits,
  671.                (PixmapPtr)pScreen->devPrivate,
  672.                pGC,
  673.                0, 0,
  674.                pPriv->screenBits->width,
  675.                pPriv->screenBits->height,
  676.                pPriv->scrX, pPriv->scrY);
  677.     pPriv->state = CR_OUT;
  678.     spriteCursorGone();
  679.     }
  680. }
  681.  
  682. /*-
  683.  *-----------------------------------------------------------------------
  684.  * spritePutCursor --
  685.  *    Place the current cursor in the screen at the given coordinates.
  686.  *    screenBits must already have been filled. If 'direct' is FALSE,
  687.  *    the cursor will be drawn into the temp pixmap after the screenBits
  688.  *    have been copied there. The temp pixmap will then be put onto
  689.  *    the screen. Used for more flicker-free cursor motion...
  690.  *
  691.  * Results:
  692.  *    None.
  693.  *
  694.  * Side Effects:
  695.  *    The state field of the private data is set to CR_IN...
  696.  *
  697.  *-----------------------------------------------------------------------
  698.  */
  699.  
  700. static void
  701. spritePutCursor (pScreen, pPriv, hotX, hotY, direct)
  702.     ScreenPtr          pScreen;        /* Screen on which to put it */
  703.     CrPrivPtr          pPriv;            /* Cursor-private data */
  704.     int                  hotX;
  705.     int                  hotY;
  706.     Bool              direct;            /* TRUE if should put the cursor */
  707.                     /* directly onto the screen, not */
  708.                     /* into pPriv->temp first... */
  709. {
  710.     register PixmapPtr    pPixmap;
  711.     register GC          *pGC;
  712.     int           realW,
  713.             realH;
  714.     int            x = hotX - currentCursor->xhot;
  715.     int         y = hotY - currentCursor->yhot;
  716.     
  717.  
  718.     pGC = spriteFbs[pScreen->myNum].pGC;
  719.  
  720.     if (!direct) {
  721.     pPixmap = pPriv->temp;
  722.     
  723.     /*
  724.      * Duplicate the contents of the screen
  725.      */
  726.     pGC->stateChanges |= (GCForeground|GCBackground);
  727.         /* Need to set some bits */
  728.     ValidateGC(pPixmap, pGC);
  729.     (* pGC->CopyArea) (pPriv->screenBits, pPixmap, pGC,
  730.                0, 0, pPixmap->width, pPixmap->height,
  731.                0, 0);
  732.     
  733.     /*
  734.      * First the foreground pixels...
  735.      * Warning: The srcGC is validated with the screen, so the clip list
  736.      * here will be wrong, but it shouldn't matter since we never go
  737.      * outside the pixmap...
  738.      */
  739.     (* pPriv->srcGC->PushPixels) (pPriv->srcGC, pPriv->source, pPixmap,
  740.                       pPriv->source->width,
  741.                       pPriv->source->height,
  742.                       x - pPriv->scrX, y - pPriv->scrY);
  743.  
  744.     /*
  745.      * Then the background pixels
  746.      */
  747.     (* pPriv->invSrcGC->PushPixels) (pPriv->invSrcGC, pPriv->invSource,
  748.                      pPixmap, pPriv->invSource->width,
  749.                      pPriv->invSource->height,
  750.                      x - pPriv->scrX, y - pPriv->scrY);
  751.  
  752.     /*
  753.      * Now put the whole buffer onto the screen
  754.      */
  755.     pPriv->state = CR_XING;
  756.     realW = min(pPixmap->width, pScreen->width - pPriv->scrX);
  757.     realH = min(pPixmap->height,pScreen->height - pPriv->scrY);
  758.  
  759.     pGC->stateChanges |= (GCForeground|GCBackground);
  760.         /* Need to set some bits */
  761.     ValidateGC((DrawablePtr)pScreen->devPrivate, pGC);
  762.     (* pGC->CopyArea) (pPixmap, (PixmapPtr)pScreen->devPrivate, pGC,
  763.                0, 0, realW, realH, pPriv->scrX, pPriv->scrY);
  764.     
  765.     pPriv->state = CR_IN;
  766.     } else {
  767.     pPixmap = (PixmapPtr) pScreen->devPrivate;
  768.  
  769.     /*
  770.      * PushPixels can't handle negative x and y.  Therefore
  771.      * we'll clip here on our own.
  772.      */
  773.     realW = min(pPriv->source->width,pPixmap->width - x);
  774.     realH = min(pPriv->source->height,pPixmap->height - y);
  775.  
  776.     pPriv->state = CR_XING;
  777.     /*
  778.      * First the foreground pixels...
  779.      */
  780.     (* pPriv->srcGC->PushPixels) (pPriv->srcGC, pPriv->source, pPixmap,
  781.                       realW, realH, x, y);
  782.     
  783.     /*
  784.      * Then the background pixels
  785.      */
  786.     (* pPriv->invSrcGC->PushPixels) (pPriv->invSrcGC, pPriv->invSource,
  787.                      pPixmap, realW, realH, x, y);
  788.  
  789.     pPriv->state = CR_IN;
  790.     }
  791. }
  792.  
  793.  
  794. /*-
  795.  *-----------------------------------------------------------------------
  796.  * spriteCursorLoc --
  797.  *    If the current cursor is both on and in the given screen,
  798.  *    fill in the given BoxRec with the extent of the cursor and return
  799.  *    TRUE. If the cursor is either on a different screen or not
  800.  *    currently in the frame buffer, return FALSE.
  801.  *
  802.  * Results:
  803.  *    TRUE or FALSE, as above.
  804.  *
  805.  * Side Effects:
  806.  *    None.
  807.  *
  808.  *-----------------------------------------------------------------------
  809.  */
  810. Bool
  811. spriteCursorLoc (pScreen, pBox)
  812.     ScreenPtr      pScreen;      /* Affected screen */
  813.     BoxRec      *pBox;    /* Box in which to place the limits */
  814. {
  815.     PtrPrivPtr      pptrPriv;
  816.     CrPrivPtr      pPriv;
  817.     DevicePtr      pDev;
  818.  
  819.     if (currentCursor == NullCursor) {
  820.     /*
  821.      * Firewall: Might be called when initially putting down the cursor
  822.      */
  823.     return FALSE;
  824.     }
  825.  
  826.     pDev = LookupPointerDevice();
  827.     pptrPriv = (PtrPrivPtr) pDev->devicePrivate;
  828.     pPriv = (CrPrivPtr) currentCursor->devPriv[pScreen->myNum];
  829.  
  830.     if ((pptrPriv->pScreen == pScreen) && (pPriv->state == CR_IN)) {
  831.     /*
  832.      * If the cursor is actually on the same screen, stuff the cursor's
  833.      * limits in the given BoxRec. Perhaps this should be done when
  834.      * the cursor is moved? Probably not important...
  835.      */
  836.  
  837.     pBox->x1 = pPriv->scrX;
  838.     pBox->y1 = pPriv->scrY;
  839.     pBox->x2 = pPriv->scrX + pPriv->screenBits->width;
  840.     pBox->y2 = pPriv->scrY + pPriv->screenBits->height;
  841.     return TRUE;
  842.     } else {
  843.     return FALSE;
  844.     }
  845. }
  846.  
  847. /*-
  848.  *-----------------------------------------------------------------------
  849.  * spriteRestoreCursor --
  850.  *    Redraw the cursor if it was removed.
  851.  *
  852.  * Results:
  853.  *    None.
  854.  *
  855.  * Side Effects:
  856.  *    The cursor may be replaced and the 'state' field changed.
  857.  *
  858.  *-----------------------------------------------------------------------
  859.  */
  860. void
  861. spriteRestoreCursor()
  862. {
  863.     PtrPrivPtr          pptrPriv;
  864.     CrPrivPtr          pPriv;
  865.     ScreenPtr          pScreen;
  866.     DevicePtr        pDev;
  867.     GC                  *pGC;
  868.     register PixmapPtr    screenBits;
  869.     int                  scrX, scrY;
  870.  
  871.     pDev = LookupPointerDevice();
  872.  
  873.     pptrPriv = (PtrPrivPtr) pDev->devicePrivate;
  874.     pScreen = pptrPriv->pScreen;
  875.     pPriv = (CrPrivPtr) currentCursor->devPriv[pScreen->myNum];
  876.     screenBits = pPriv->screenBits;
  877.  
  878.     if (pPriv->state == CR_OUT) {
  879.     /*
  880.      * Since the buffer pixmap is four times as large as the cursor and
  881.      * we would always like to center the thing so as to allow the same
  882.      * leeway for movement, in spriteMoveCursor, on each side, we place the
  883.      * top-left corner of the cursor at the intersection of the first
  884.      * quarter lines by shifting the position of the buffer pixmap
  885.      */
  886.     scrX = pptrPriv->x - currentCursor->xhot - screenBits->width / 4;
  887.     scrY = pptrPriv->y - currentCursor->yhot - screenBits->height / 4;
  888.  
  889.     /*
  890.      * In general we're trying to store some of the bits surrounding the
  891.      * cursor.  We try to center the cursor in the area we're
  892.          * saving; that is what the previous two lines are doing.  But if we're
  893.          * at the top left already, we won't try to center the cursor; we'll
  894.      * just save from [0,0].
  895.      */
  896.     if (scrX < 0) {
  897.         scrX = 0;
  898.     }
  899.     if (scrY < 0) {
  900.         scrY = 0;
  901.     }
  902.  
  903.     pPriv->scrX = scrX;
  904.     pPriv->scrY = scrY;
  905.     
  906.     pGC = spriteFbs[pScreen->myNum].pGC;
  907.     pGC->stateChanges |= (GCForeground|GCBackground);    
  908.         /* Need to set some bits */
  909.     ValidateGC(screenBits, pGC);
  910.     (* pGC->CopyArea) ((DrawablePtr)pScreen->devPrivate,
  911.                (DrawablePtr)screenBits,
  912.                pGC,
  913.                scrX, scrY,
  914.                screenBits->width, screenBits->height,
  915.                0, 0);
  916.     spritePutCursor (pScreen, pPriv, pptrPriv->x, pptrPriv->y, TRUE);
  917.     }
  918. }
  919.  
  920. /*-
  921.  *-----------------------------------------------------------------------
  922.  * spriteMoveCursor --
  923.  *    Shift a the current cursor by a given amount. If the change keeps
  924.  *    the cursor within its screenBits pixmap, the whole thing is
  925.  *    simply drawn over the old position. Otherwise, the cursor is
  926.  *    removed and must be redrawn before we sleep. The pointer's
  927.  *    coordinates need not have been updated before this is called.
  928.  *
  929.  * Results:
  930.  *    None.
  931.  *
  932.  * Side Effects:
  933.  *    The cursor may be removed...
  934.  *
  935.  *-----------------------------------------------------------------------
  936.  */
  937. void
  938. spriteMoveCursor (pScreen, hotX, hotY)
  939.     ScreenPtr      pScreen;      /* Screen cursor's currently on */
  940.     int              hotX;          /* Cursor's new X coordinate */
  941.     int              hotY;          /* Cursor's new Y coordinate */
  942. {
  943.     CrPrivPtr      pPriv;
  944.  
  945.     pPriv = (CrPrivPtr) currentCursor->devPriv[pScreen->myNum];
  946.  
  947.     if (pPriv->state == CR_OUT) {
  948.     return;
  949.     }
  950.  
  951.     if ((hotX - currentCursor->xhot >= pPriv->scrX) &&
  952.     ((hotX - currentCursor->xhot + currentCursor->width) <
  953.      (pPriv->scrX + pPriv->screenBits->width))&&
  954.     (hotY - currentCursor->yhot >= pPriv->scrY) &&
  955.     ((hotY - currentCursor->yhot + currentCursor->height) <
  956.      (pPriv->scrY + pPriv->screenBits->height))) {
  957.          /*
  958.           * If the entire cursor at its new position remains inside the
  959.           * box buffered in the screenBits pixmap, then its ok to just
  960.           * place the cursor inside the box and draw the entire box
  961.           * onto the screen. The hope is that this redrawing, rather than
  962.           * removing the cursor and redrawing it, will cause it to flicker
  963.           * less than it did in V10...
  964.           */
  965.          spritePutCursor (pScreen, pPriv, hotX, hotY, FALSE);
  966.     } else {
  967.     /*
  968.      * The cursor is no longer within the screenBits pixmap, so we just
  969.      * remove it. dix will RestoreCursor() it back onto the screen.
  970.      */
  971.     spriteRemoveCursor();
  972.     }
  973. }
  974.  
  975. /*-
  976.  *-----------------------------------------------------------------------
  977.  * spriteConstrainXY --
  978.  *    Given an X and Y coordinate, alter them to fit within the current
  979.  *    cursor constraints.  Used by mouse processing code to adjust 
  980.  *     position reported by hardware.
  981.  *    
  982.  *
  983.  * Results:
  984.  *    The new constrained coordinates. Returns FALSE if the motion
  985.  *    event should be discarded...
  986.  *
  987.  * Side Effects:
  988.  *    guess what?
  989.  *
  990.  *-----------------------------------------------------------------------
  991.  */
  992. Bool
  993. spriteConstrainXY (px, py)
  994.     short      *px;
  995.     short           *py;    
  996. {
  997.     *px = max(currentLimits.x1,min(currentLimits.x2,*px));
  998.     *py = max(currentLimits.y1,min(currentLimits.y2,*py));
  999.     return TRUE;
  1000. }
  1001.  
  1002. /*-
  1003.  *-----------------------------------------------------------------------
  1004.  * spritePaintWindow --
  1005.  *    Paint either the window's border or background while preserving
  1006.  *    the cursor.
  1007.  *
  1008.  * Results:
  1009.  *    None.
  1010.  *
  1011.  * Side Effects:
  1012.  *    The cursor will be removed if it is in the way.
  1013.  *
  1014.  *-----------------------------------------------------------------------
  1015.  */
  1016. void
  1017. spritePaintWindow (pWin, pRegion, what)
  1018.     WindowPtr    pWin;            /* Window to paint */
  1019.     RegionPtr    pRegion;        /* Uncovered region in which the painting
  1020.                  * should be done */
  1021.     int        what;            /* PW_BACKGROUND to paint the background
  1022.                  * PW_BORDER to paint the border */
  1023. {
  1024.     BoxRec    cursorBox;      /* Current cursor area */
  1025.     WinPrivPtr    pPriv;            /* Private data for the window */
  1026.     ScreenPtr    pScreen;        /* The screen the window is on */
  1027.  
  1028.     pScreen = pWin->drawable.pScreen;
  1029.  
  1030.     if (spriteCursorLoc (pScreen, &cursorBox)) {
  1031.     /*
  1032.      * If the cursor is on the same screen as the window, check the
  1033.      * region to paint for the cursor and remove it as necessary
  1034.      */
  1035.     if ((* pScreen->RectIn) (pRegion, &cursorBox) != rgnOUT) {
  1036.         spriteRemoveCursor();
  1037.     }
  1038.     }
  1039.  
  1040.     pPriv = (WinPrivPtr) LookupID (pWin->wid, RT_WINDOW, wPrivClass);
  1041.     if (what == PW_BACKGROUND) {
  1042.     (* pPriv->PaintWindowBackground) (pWin, pRegion, what);
  1043.     } else {
  1044.     (* pPriv->PaintWindowBorder) (pWin, pRegion, what);
  1045.     }
  1046. }
  1047.  
  1048. /*-
  1049.  *-----------------------------------------------------------------------
  1050.  * spriteCopyWindow --
  1051.  *    Protect the cursor from window copies..
  1052.  *
  1053.  * Results:
  1054.  *    None.
  1055.  *
  1056.  * Side Effects:
  1057.  *    The cursor may be removed.
  1058.  *
  1059.  *-----------------------------------------------------------------------
  1060.  */
  1061. void
  1062. spriteCopyWindow (pWin, ptOldOrg, prgnSrc)
  1063.     WindowPtr      pWin;        /* Window being copied */
  1064.     DDXPointRec      ptOldOrg; /* Old absolute origin for window */
  1065.     RegionPtr      prgnSrc;  /* Region from which window is being copied. */
  1066. {
  1067.     BoxRec    cursorBox;
  1068.     WinPrivPtr    pPriv;
  1069.     ScreenPtr    pScreen;
  1070.  
  1071.     pScreen = pWin->drawable.pScreen;
  1072.  
  1073.     if (spriteCursorLoc (pScreen, &cursorBox)) {
  1074.     /*
  1075.      * If the cursor is on the same screen, compare the box for the
  1076.      * cursor against the original window clip region (prgnSrc) and
  1077.      * the current window clip region (pWin->borderClip) and if it
  1078.      * overlaps either one, remove the cursor. (Should it really be
  1079.      * borderClip?)
  1080.      */
  1081.     switch ((* pScreen->RectIn) (prgnSrc, &cursorBox)) {
  1082.         case rgnOUT:
  1083.         if ((* pScreen->RectIn) (pWin->borderClip, &cursorBox) ==
  1084.             rgnOUT) {
  1085.             break;
  1086.         }
  1087.         case rgnIN:
  1088.         case rgnPART:
  1089.         spriteRemoveCursor();
  1090.     }
  1091.     }
  1092.  
  1093.     pPriv = (WinPrivPtr) LookupID (pWin->wid, RT_WINDOW, wPrivClass);
  1094.     (* pPriv->CopyWindow) (pWin, ptOldOrg, prgnSrc);
  1095. }
  1096.  
  1097. /*-
  1098.  *-----------------------------------------------------------------------
  1099.  * spriteSaveAreas --
  1100.  *    Keep the cursor from getting in the way of any SaveAreas operation
  1101.  *    by backing-store.
  1102.  *
  1103.  * Results:
  1104.  *    None.
  1105.  *
  1106.  * Side Effects:
  1107.  *    The cursor may be removed.
  1108.  *
  1109.  *-----------------------------------------------------------------------
  1110.  */
  1111. void
  1112. spriteSaveAreas(pWin)
  1113.     WindowPtr      pWin;
  1114. {
  1115.     BoxRec        cursorBox;
  1116.     WinPrivPtr      pPriv;
  1117.     ScreenPtr      pScreen;
  1118.  
  1119.     pScreen = pWin->drawable.pScreen;
  1120.  
  1121.     if (spriteCursorLoc(pScreen, &cursorBox)) {
  1122.     /*
  1123.      * If the areas are obscured because the window moved, we need to
  1124.      * translate the box to the correct relationship with the region,
  1125.      * which is at the new window coordinates.
  1126.      */
  1127.     int dx, dy;
  1128.  
  1129.     dx = pWin->absCorner.x - pWin->backStorage->oldAbsCorner.x;
  1130.     dy = pWin->absCorner.y - pWin->backStorage->oldAbsCorner.y;
  1131.  
  1132.     if (dx || dy) {
  1133.         cursorBox.x1 += dx;
  1134.         cursorBox.y1 += dy;
  1135.         cursorBox.x2 += dx;
  1136.         cursorBox.y2 += dy;
  1137.     }
  1138.     if ((* pScreen->RectIn) (pWin->backStorage->obscured, &cursorBox) != rgnOUT) {
  1139.         spriteRemoveCursor();
  1140.     }
  1141.     }
  1142.     pPriv = (WinPrivPtr) LookupID (pWin->wid, RT_WINDOW, wPrivClass);
  1143.     (* pPriv->SaveAreas) (pWin);
  1144. }
  1145.  
  1146. /*-
  1147.  *-----------------------------------------------------------------------
  1148.  * spriteRestoreAreas --
  1149.  *    Keep the cursor from getting in the way of any RestoreAreas operation
  1150.  *    by backing-store.
  1151.  *
  1152.  * Results:
  1153.  *    None.
  1154.  *
  1155.  * Side Effects:
  1156.  *    The cursor may be removed.
  1157.  *
  1158.  *-----------------------------------------------------------------------
  1159.  */
  1160. RegionPtr
  1161. spriteRestoreAreas(pWin)
  1162.     WindowPtr      pWin;
  1163. {
  1164.     BoxRec        cursorBox;
  1165.     WinPrivPtr      pPriv;
  1166.     ScreenPtr      pScreen;
  1167.  
  1168.     pScreen = pWin->drawable.pScreen;
  1169.  
  1170.     if (spriteCursorLoc(pScreen, &cursorBox)) {
  1171.     /*
  1172.      * The exposed region is now window-relative, so we have to make the
  1173.      * cursor box window-relative too.
  1174.      */
  1175.     cursorBox.x1 -= pWin->absCorner.x;
  1176.     cursorBox.x2 -= pWin->absCorner.x;
  1177.     cursorBox.y1 -= pWin->absCorner.y;
  1178.     cursorBox.y2 -= pWin->absCorner.y;
  1179.     if ((* pScreen->RectIn) (pWin->exposed, &cursorBox) != rgnOUT) {
  1180.         spriteRemoveCursor();
  1181.     }
  1182.     }
  1183.     pPriv = (WinPrivPtr) LookupID (pWin->wid, RT_WINDOW, wPrivClass);
  1184.     return (* pPriv->RestoreAreas) (pWin);
  1185. }
  1186.  
  1187. /*-
  1188.  *-----------------------------------------------------------------------
  1189.  * spriteCreateWindow --
  1190.  *    A way to get our hooks into a new window to keep the cursor from
  1191.  *    being obliterated. We first allow the output library for the
  1192.  *    screen to install its vectors and then stuff our own in their
  1193.  *    places.
  1194.  *
  1195.  * Results:
  1196.  *    TRUE.
  1197.  *
  1198.  * Side Effects:
  1199.  *    A WinPrivRec is allocated and stored under the window's ID.
  1200.  *    The PaintWindowBackground and PaintWindowBorder and CopyWindow
  1201.  *    vectors for the new window are overwritten.
  1202.  *
  1203.  *-----------------------------------------------------------------------
  1204.  */
  1205. Bool
  1206. spriteCreateWindow (pWin)
  1207.     WindowPtr    pWin;
  1208. {
  1209.     WinPrivPtr    pPriv;
  1210.  
  1211.     (* spriteFbs[((DrawablePtr)pWin)->pScreen->myNum].CreateWindow) (pWin);
  1212.  
  1213.     pPriv = (WinPrivPtr) Xalloc (sizeof (WinPrivRec));
  1214.     pPriv->PaintWindowBackground =  pWin->PaintWindowBackground;
  1215.     pPriv->PaintWindowBorder =         pWin->PaintWindowBorder;
  1216.     pPriv->CopyWindow =             pWin->CopyWindow;
  1217.  
  1218.     pWin->PaintWindowBackground =   spritePaintWindow;
  1219.     pWin->PaintWindowBorder =         spritePaintWindow;
  1220.     pWin->CopyWindow =                spriteCopyWindow;
  1221.  
  1222.     if (pWin->backStorage) {
  1223.     pPriv->SaveAreas = pWin->backStorage->SaveDoomedAreas;
  1224.     pWin->backStorage->SaveDoomedAreas = spriteSaveAreas;
  1225.     pPriv->RestoreAreas = pWin->backStorage->RestoreAreas;
  1226.     pWin->backStorage->RestoreAreas = spriteRestoreAreas;
  1227.     }
  1228.     AddResource (pWin->wid, RT_WINDOW, (pointer)pPriv, Xfree, wPrivClass);
  1229. }
  1230.  
  1231. /*-
  1232.  *-----------------------------------------------------------------------
  1233.  * spriteChangeWindowAttributes --
  1234.  *    Catch the changing of the background/border functions when a
  1235.  *    window is reconfigured.
  1236.  *
  1237.  * Results:
  1238.  *    TRUE.
  1239.  *
  1240.  * Side Effects:
  1241.  *    The three vectors we intercept will be restored to the rightful
  1242.  *    value if they have been changed.
  1243.  *
  1244.  *-----------------------------------------------------------------------
  1245.  */
  1246. Bool
  1247. spriteChangeWindowAttributes (pWin, mask)
  1248.     WindowPtr    pWin;        /* Window being altered */
  1249.     Mask    mask;        /* Mask of changes to the window */
  1250. {
  1251.     WinPrivPtr    pPriv;
  1252.  
  1253.     (* spriteFbs[((DrawablePtr)pWin)->pScreen->myNum].ChangeWindowAttributes)
  1254.     (pWin, mask);
  1255.     
  1256.     pPriv = (WinPrivPtr) LookupID (pWin->wid, RT_WINDOW, wPrivClass);
  1257.  
  1258.     if (pPriv == (WinPrivPtr)0) {
  1259.     FatalError ("spriteChangeWindowAttributes got null private data");
  1260.     }
  1261.  
  1262.     if ((void (*)())pWin->PaintWindowBackground !=
  1263.     (void (*)())spritePaintWindow){
  1264.         pPriv->PaintWindowBackground = pWin->PaintWindowBackground;
  1265.         pWin->PaintWindowBackground = spritePaintWindow;
  1266.     }
  1267.  
  1268.     if ((void (*)())pWin->PaintWindowBorder !=
  1269.     (void (*)())spritePaintWindow) {
  1270.         pPriv->PaintWindowBorder = pWin->PaintWindowBorder;
  1271.         pWin->PaintWindowBorder = spritePaintWindow;
  1272.     }
  1273.  
  1274.     if ((void (*)())pWin->CopyWindow != (void (*)())spriteCopyWindow) {
  1275.     pPriv->CopyWindow = pWin->CopyWindow;
  1276.     pWin->CopyWindow = spriteCopyWindow;
  1277.     }
  1278.  
  1279.     if (pWin->backStorage &&
  1280.     ((void (*)())pWin->backStorage->SaveDoomedAreas != (void (*)())spriteSaveAreas)){
  1281.         pPriv->SaveAreas = pWin->backStorage->SaveDoomedAreas;
  1282.         pWin->backStorage->SaveDoomedAreas = spriteSaveAreas;
  1283.     }
  1284.     if (pWin->backStorage &&
  1285.     ((void (*)())pWin->backStorage->RestoreAreas != (void (*)())spriteRestoreAreas)){
  1286.         pPriv->RestoreAreas = pWin->backStorage->RestoreAreas;
  1287.         pWin->backStorage->RestoreAreas = spriteRestoreAreas;
  1288.     }
  1289.  
  1290.     return (TRUE);
  1291. }
  1292.  
  1293. @
  1294.  
  1295.  
  1296. 1.11
  1297. log
  1298. @*** empty log message ***
  1299. @
  1300. text
  1301. @d18 1
  1302. a18 1
  1303. "$Header: spriteCursor.c,v 1.10 88/02/19 17:36:58 deboor Exp $ SPRITE (Berkeley)";
  1304. d67 1
  1305. a67 1
  1306.     void        (*RestoreAreas)();
  1307. d1086 1
  1308. a1086 1
  1309. void
  1310. d1110 1
  1311. a1110 1
  1312.     (* pPriv->RestoreAreas) (pWin);
  1313. @
  1314.  
  1315.  
  1316. 1.10
  1317. log
  1318. @Lots o' changes to bring up-to-date with R1
  1319. @
  1320. text
  1321. @d18 1
  1322. a18 1
  1323. "$Header: spriteCursor.c,v 1.9 87/08/21 20:36:26 deboor Exp $ SPRITE (Berkeley)";
  1324. d66 2
  1325. d1025 90
  1326. d1148 6
  1327. d1203 11
  1328. @
  1329.  
  1330.  
  1331. 1.9
  1332. log
  1333. @Fixed file header to reflect the correct file name
  1334. @
  1335. text
  1336. @d18 1
  1337. a18 1
  1338. "$Header: spriteCursor.c,v 1.8 87/07/07 17:59:31 deboor Exp $ SPRITE (Berkeley)";
  1339. d36 1
  1340. d43 1
  1341. a72 2
  1342.  
  1343.  
  1344. d158 2
  1345. a159 1
  1346.     FatalError("Can't alloc pixel (%d,%d,%d) in spriteGetPixel\n");
  1347. d300 4
  1348. d313 2
  1349. a314 2
  1350.     FreeGC(pPriv->srcGC);
  1351.     FreeGC(pPriv->invSrcGC);
  1352. d325 1
  1353. a325 4
  1354.  *    are assumed to be legal for the given screen. If there is a
  1355.  *    a current cursor, we just call spriteDisplayCursor to force the
  1356.  *    cursor to be removed as well. spriteDisplayCursor will take care
  1357.  *    of setting the position parameters.
  1358. d338 1
  1359. a338 1
  1360. spriteSetCursorPosition (pScreen, hotX, hotY)
  1361. d342 1
  1362. d344 5
  1363. a348 5
  1364.     if (currentCursor) {
  1365.     /*
  1366.      * It's just as easy to pretend a new cursor is being displayed...
  1367.      */
  1368.     spriteDisplayCursor (pScreen, currentCursor, hotX, hotY);
  1369. d350 1
  1370. a350 2
  1371.     DevicePtr      pDev;
  1372.     PtrPrivPtr      pptrPriv;
  1373. d352 1
  1374. a352 1
  1375.     pDev = LookupPointerDevice();
  1376. d354 8
  1377. a361 1
  1378.     pptrPriv = (PtrPrivPtr)pDev->devicePrivate;
  1379. d363 14
  1380. a376 1
  1381.     pptrPriv->pScreen = pScreen;
  1382. d379 18
  1383. a397 1
  1384.     return TRUE;
  1385. d437 1
  1386. a437 2
  1387.  *    be replaced. The initial position of the cursor's hot-spot is set
  1388.  *    from the hotX and hotY arguments.
  1389. d442 1
  1390. a442 1
  1391. spriteDisplayCursor (pScreen, pCursor, hotX, hotY)
  1392. a444 2
  1393.     int          hotX;            /* Initial X position for cursor */
  1394.     int       hotY;            /* Initial Y position for cursor */
  1395. a445 3
  1396.     DevicePtr      pDev;
  1397.     PtrPrivPtr      pptrPriv;
  1398.  
  1399. a454 8
  1400.     pDev = LookupPointerDevice();
  1401.  
  1402.     pptrPriv = (PtrPrivPtr)pDev->devicePrivate;
  1403.     
  1404.     pptrPriv->pScreen = pScreen;
  1405.     pptrPriv->x = hotX;
  1406.     pptrPriv->y = hotY;
  1407.  
  1408. d533 1
  1409. a533 1
  1410.  *    None, for now.
  1411. d570 4
  1412. d754 1
  1413. a754 1
  1414.     if (pptrPriv->pScreen == pScreen && pPriv->state == CR_IN) {
  1415. a926 4
  1416.  * spritePaintWindowBackground --
  1417.  *    Paint the window's background while preserving the cursor
  1418.  */
  1419. /*-
  1420. d1056 1
  1421. a1056 2
  1422.     AddResource (pWin->wid, RT_WINDOW, (pointer)pPriv, Xfree, 
  1423.          wPrivClass);
  1424. @
  1425.  
  1426.  
  1427. 1.8
  1428. log
  1429. @Fixed to account for color, if I ever add it.
  1430. @
  1431. text
  1432. @d2 1
  1433. a2 1
  1434.  * sunCursor.c --
  1435. d18 1
  1436. a18 1
  1437. "$Header: spriteCursor.c,v 1.7 87/06/30 19:11:02 deboor Exp $ SPRITE (Berkeley)";
  1438. @
  1439.  
  1440.  
  1441. 1.7
  1442. log
  1443. @Changed to use a scratch GC. This should probably be changed
  1444. @
  1445. text
  1446. @d18 1
  1447. a18 1
  1448. "$Header: spriteCursor.c,v 1.6 87/06/28 14:12:56 deboor Exp $ SPRITE (Berkeley)";
  1449. d192 1
  1450. a192 1
  1451.     pGC = GetScratchGC (pScreen->rootDepth, pScreen);
  1452. d251 2
  1453. a252 2
  1454.     pPriv->srcGC = spriteCreatePrivGC(pPriv->source, GCForeground,
  1455.                    &pPriv->fg, &status);
  1456. d271 2
  1457. a272 2
  1458.     pPriv->invSrcGC = spriteCreatePrivGC(pPriv->invSource, GCForeground,
  1459.                       &pPriv->bg, &status);
  1460. d274 2
  1461. d559 1
  1462. a559 1
  1463.     pGC = GetScratchGC (pScreen->rootDepth, pScreen);
  1464. d613 1
  1465. a613 1
  1466.     pGC = GetScratchGC (pScreen->rootDepth, pScreen);
  1467. d801 1
  1468. a801 1
  1469.     pGC = GetScratchGC (pScreen->rootDepth, pScreen);
  1470. @
  1471.  
  1472.  
  1473. 1.5
  1474. log
  1475. @Fixed spriteGetPixel so it doesn't always return Black
  1476. @
  1477. text
  1478. @d18 1
  1479. a18 1
  1480. "$Header: spriteCursor.c,v 1.4 87/06/20 19:56:38 deboor Exp $ SPRITE (Berkeley)";
  1481. d192 1
  1482. a192 1
  1483.     pGC = spriteFbs[pScreen->myNum].pGC;
  1484. d318 4
  1485. a321 1
  1486.  *    are assumed to be legal for the given screen.
  1487. d339 10
  1488. a348 2
  1489.     DevicePtr      pDev;
  1490.     PtrPrivPtr      pptrPriv;
  1491. d350 5
  1492. a354 2
  1493.     if (currentCursor) {
  1494.     spriteDisplayCursor (pScreen, currentCursor);
  1495. a355 8
  1496.     
  1497.     pDev = LookupPointerDevice();
  1498.  
  1499.     pptrPriv = (PtrPrivPtr)pDev->devicePrivate;
  1500.  
  1501.     pptrPriv->pScreen = pScreen;
  1502.     pptrPriv->x = hotX;
  1503.     pptrPriv->y = hotY;
  1504. d396 2
  1505. a397 1
  1506.  *    be replaced.
  1507. a400 1
  1508. /* ARGSUSED */
  1509. d405 2
  1510. a406 2
  1511.     int          hotX;
  1512.     int       hotY;
  1513. d408 2
  1514. a409 1
  1515.     DevicePtr          pDev;
  1516. d416 1
  1517. d422 5
  1518. a426 3
  1519.     if (pScreen != ((PtrPrivPtr)pDev->devicePrivate)->pScreen) {
  1520.     ((PtrPrivPtr)pDev->devicePrivate)->pScreen = pScreen;
  1521.     }
  1522. d557 1
  1523. a557 1
  1524.     pGC = spriteFbs[pScreen->myNum].pGC;
  1525. d611 1
  1526. a611 1
  1527.     pGC = spriteFbs[pScreen->myNum].pGC;
  1528. d799 1
  1529. a799 1
  1530.     pGC = spriteFbs[pScreen->myNum].pGC;
  1531. @
  1532.  
  1533.  
  1534. 1.4
  1535. log
  1536. @adapted to Beta-0
  1537. @
  1538. text
  1539. @d18 1
  1540. a18 1
  1541. "$Header: spriteCursor.c,v 1.3 87/06/20 14:58:26 deboor Exp $ SPRITE (Berkeley)";
  1542. d146 3
  1543. a148 3
  1544.     int              r;        /* Red value to use */
  1545.     int              g;        /* Green value to use */
  1546.     int              b;        /* Blue value to use */
  1547. @
  1548.  
  1549.  
  1550. 1.3
  1551. log
  1552. @Re-added rcsid.
  1553. @
  1554. text
  1555. @d18 1
  1556. a18 1
  1557. "$Header$ SPRITE (Berkeley)";
  1558. d108 1
  1559. a108 1
  1560. static u_char *
  1561. d110 2
  1562. a111 2
  1563.     register u_char *source;      /* Source data */
  1564.     register u_char *mask;        /* Mask data */
  1565. d116 2
  1566. a117 2
  1567.     u_char          *result;
  1568.     register u_char *r;
  1569. d121 1
  1570. a121 1
  1571.     result = (u_char *)Xalloc(nbytes);
  1572. d188 1
  1573. a188 1
  1574.     u_char     *stencil;
  1575. @
  1576.  
  1577.  
  1578. 1.2
  1579. log
  1580. @beep
  1581. @
  1582. text
  1583. @d16 4
  1584. @
  1585.  
  1586.  
  1587. 1.1
  1588. log
  1589. @Initial revision
  1590. @
  1591. text
  1592. @d25 2
  1593. a26 2
  1594.  * The outside world (dix code) and most of sunCursors use the cursor 
  1595.  * hot-spot as a reference for the cursor's location. sunCursor internal 
  1596. d32 1
  1597. a32 1
  1598. #include    "sun.h"
  1599. d71 1
  1600. a71 1
  1601.  * sunInitCursor --
  1602. d83 1
  1603. a83 1
  1604. sunInitCursor ()
  1605. d91 1
  1606. a91 1
  1607.  * Stencil --
  1608. d105 1
  1609. a105 1
  1610. sunStencil (source, mask, w, h, invert)
  1611. d128 1
  1612. a128 1
  1613.  * sunGetPixel --
  1614. d140 1
  1615. a140 1
  1616. sunGetPixel (pScreen, r, g, b)
  1617. d151 1
  1618. a151 1
  1619.     FatalError("Can't find default colormap in sunGetPixel\n");
  1620. d154 1
  1621. a154 1
  1622.     FatalError("Can't alloc pixel (%d,%d,%d) in sunGetPixel\n");
  1623. d160 1
  1624. a160 1
  1625.  * sunRealizeCursor --
  1626. d175 1
  1627. a175 1
  1628. sunRealizeCursor (pScreen, pCursor)
  1629. d188 1
  1630. a188 1
  1631.     pGC = sunFbs[pScreen->myNum].pGC;
  1632. d196 1
  1633. a196 1
  1634.     pPriv->fg = sunGetPixel(pScreen, pCursor->foreRed,
  1635. d199 1
  1636. a199 1
  1637.     pPriv->bg = sunGetPixel(pScreen, pCursor->backRed,
  1638. d236 1
  1639. a236 1
  1640.     stencil = sunStencil(pCursor->source, pCursor->mask,
  1641. d247 1
  1642. a247 1
  1643.     pPriv->srcGC = sunCreatePrivGC(pPriv->source, GCForeground,
  1644. d256 1
  1645. a256 1
  1646.     stencil = sunStencil(pCursor->source, pCursor->mask,
  1647. d267 1
  1648. a267 1
  1649.     pPriv->invSrcGC = sunCreatePrivGC(pPriv->invSource, GCForeground,
  1650. d274 2
  1651. a275 2
  1652.  * sunUnrealizeCursor --
  1653.  *    Free up the extra state created by sunRealizeCursor.
  1654. d281 1
  1655. a281 1
  1656.  *    All the pixmaps etc. created by sunRealizeCursor are destroyed
  1657. d287 1
  1658. a287 1
  1659. sunUnrealizeCursor (pScreen, pCursor)
  1660. d312 1
  1661. a312 1
  1662.  * sunSetCursorPosition --
  1663. d327 1
  1664. a327 1
  1665. sunSetCursorPosition (pScreen, hotX, hotY)
  1666. d336 1
  1667. a336 1
  1668.     sunDisplayCursor (pScreen, currentCursor);
  1669. d351 1
  1670. a351 1
  1671.  * sunCursorLimits --
  1672. d365 1
  1673. a365 1
  1674. sunCursorLimits (pScreen, pCursor, pHotBox, pResultBox)
  1675. d376 1
  1676. a376 1
  1677.  * sunDisplayCursor --
  1678. d392 1
  1679. a392 1
  1680. sunDisplayCursor (pScreen, pCursor, hotX, hotY)
  1681. d401 1
  1682. a401 1
  1683.     sunRemoveCursor();
  1684. d419 1
  1685. a419 1
  1686.  * sunRecolorCursor --
  1687. d431 1
  1688. a431 1
  1689. sunRecolorCursor (pScreen, pCursor, displayed)
  1690. d444 1
  1691. a444 1
  1692.     sunRemoveCursor();
  1693. d448 1
  1694. a448 1
  1695.     pPriv->fg = sunGetPixel(pScreen,
  1696. d455 1
  1697. a455 1
  1698.     pPriv->bg = sunGetPixel (pScreen,
  1699. d465 1
  1700. a465 1
  1701.  * sunPointerNonInterestBox --
  1702. d476 1
  1703. a476 1
  1704. sunPointerNonInterestBox (pScreen, pBox)
  1705. d484 1
  1706. a484 1
  1707.  * sunConstrainCursor --
  1708. d498 1
  1709. a498 1
  1710. sunConstrainCursor (pScreen, pBox)
  1711. d507 1
  1712. a507 1
  1713.  * sunRemoveCursor --
  1714. d516 1
  1715. a516 1
  1716.  *    structure is set to CR_OUT. In addition, sunInputAvail is called.
  1717. d521 1
  1718. a521 1
  1719. sunRemoveCursor ()
  1720. d543 1
  1721. a543 1
  1722.     pGC = sunFbs[pScreen->myNum].pGC;
  1723. d563 1
  1724. a563 1
  1725.  * sunPutCursor --
  1726. d580 1
  1727. a580 1
  1728. sunPutCursor (pScreen, pPriv, hotX, hotY, direct)
  1729. d597 1
  1730. a597 1
  1731.     pGC = sunFbs[pScreen->myNum].pGC;
  1732. d675 1
  1733. a675 1
  1734.  * sunCursorLoc --
  1735. d690 1
  1736. a690 1
  1737. sunCursorLoc (pScreen, pBox)
  1738. d728 1
  1739. a728 1
  1740.  * sunRestoreCursor --
  1741. d740 1
  1742. a740 1
  1743. sunRestoreCursor()
  1744. d761 1
  1745. a761 1
  1746.      * leeway for movement, in sunMoveCursor, on each side, we place the
  1747. d785 1
  1748. a785 1
  1749.     pGC = sunFbs[pScreen->myNum].pGC;
  1750. d795 1
  1751. a795 1
  1752.     sunPutCursor (pScreen, pPriv, pptrPriv->x, pptrPriv->y, TRUE);
  1753. d801 1
  1754. a801 1
  1755.  * sunMoveCursor --
  1756. d817 1
  1757. a817 1
  1758. sunMoveCursor (pScreen, hotX, hotY)
  1759. d844 1
  1760. a844 1
  1761.          sunPutCursor (pScreen, pPriv, hotX, hotY, FALSE);
  1762. d850 1
  1763. a850 1
  1764.     sunRemoveCursor();
  1765. d856 1
  1766. a856 1
  1767.  * sunConstrainXY --
  1768. d872 1
  1769. a872 1
  1770. sunConstrainXY (px, py)
  1771. d882 1
  1772. a882 1
  1773.  * sunPaintWindowBackground --
  1774. d885 14
  1775. a898 1
  1776. #define sunPaintWindowBorder sunPaintWindowBackground
  1777. d900 6
  1778. a905 4
  1779. sunPaintWindowBackground (pWin, pRegion, what)
  1780.     WindowPtr    pWin;
  1781.     RegionPtr    pRegion;
  1782.     int        what;
  1783. d907 3
  1784. a909 3
  1785.     BoxRec    cursorBox;
  1786.     WinPrivPtr    pPriv;
  1787.     ScreenPtr    pScreen;
  1788. d913 1
  1789. a913 1
  1790.     if (sunCursorLoc (pScreen, &cursorBox)) {
  1791. d919 1
  1792. a919 1
  1793.         sunRemoveCursor();
  1794. d933 1
  1795. a933 1
  1796.  * sunCopyWindow --
  1797. d945 4
  1798. a948 4
  1799. sunCopyWindow (pWin, ptOldOrg, prgnSrc)
  1800.     WindowPtr      pWin;
  1801.     DDXPointRec      ptOldOrg;
  1802.     RegionPtr      prgnSrc;
  1803. d956 1
  1804. a956 1
  1805.     if (sunCursorLoc (pScreen, &cursorBox)) {
  1806. d972 1
  1807. a972 1
  1808.         sunRemoveCursor();
  1809. d981 16
  1810. a996 4
  1811.  * sunCreateWindow --
  1812.  *    Allow the output library to do its thing and then make sure
  1813.  *    we intercept calls to PaintWindow{Border,Background} and
  1814.  *    ClearToBackground
  1815. d999 1
  1816. a999 1
  1817. sunCreateWindow (pWin)
  1818. d1004 1
  1819. a1004 1
  1820.     (* sunFbs[((DrawablePtr)pWin)->pScreen->myNum].CreateWindow) (pWin);
  1821. d1011 3
  1822. a1013 3
  1823.     pWin->PaintWindowBackground =   sunPaintWindowBackground;
  1824.     pWin->PaintWindowBorder =         sunPaintWindowBorder;
  1825.     pWin->CopyWindow =                sunCopyWindow;
  1826. d1020 13
  1827. a1032 2
  1828.  * sunChangeWindowAttributes --
  1829.  *    Catch the changing of the background/border functions
  1830. d1035 3
  1831. a1037 3
  1832. sunChangeWindowAttributes (pWin, mask)
  1833.     WindowPtr    pWin;
  1834.     Mask    mask;
  1835. d1041 1
  1836. a1041 1
  1837.     (* sunFbs[((DrawablePtr)pWin)->pScreen->myNum].ChangeWindowAttributes)
  1838. d1047 1
  1839. a1047 1
  1840.     FatalError ("sunChangeWindowAttributes got null private data");
  1841. d1051 1
  1842. a1051 1
  1843.     (void (*)())sunPaintWindowBackground){
  1844. d1053 1
  1845. a1053 1
  1846.         pWin->PaintWindowBackground = sunPaintWindowBackground;
  1847. d1057 1
  1848. a1057 1
  1849.     (void (*)())sunPaintWindowBorder) {
  1850. d1059 1
  1851. a1059 1
  1852.         pWin->PaintWindowBorder = sunPaintWindowBorder;
  1853. d1062 1
  1854. a1062 1
  1855.     if ((void (*)())pWin->CopyWindow != (void (*)())sunCopyWindow) {
  1856. d1064 1
  1857. a1064 1
  1858.     pWin->CopyWindow = sunCopyWindow;
  1859. @
  1860.